package com.tbit.main.controller;

import com.alibaba.fastjson.JSON;
import com.tbit.main.common.JsonResult;
import com.tbit.main.constant.ControlTypeConstant;
import com.tbit.main.constant.RedisConstant;
import com.tbit.main.constant.RoleConfigConstant;
import com.tbit.main.dao.log.RuleRidePhotoLogDao;
import com.tbit.main.exception.BaseException;
import com.tbit.main.pojo.AccountConfig;
import com.tbit.main.pojo.AccountUser;
import com.tbit.main.pojo.Machine;
import com.tbit.main.pojo.RuleRidePhotoLog;
import com.tbit.main.pojo.VO.TerControlReqVO;
import com.tbit.main.service.*;
import com.tbit.main.service.ter.TerControlResult;
import com.tbit.main.util.Assert;
import com.tbit.manager.api.TerControlApi;
import com.tbit.manager.api.dto.TerControlDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * 终端控制
 *
 * @author Leon
 * 2019年11月11日 下午10:00:01
 */
@RestController
@RequestMapping("/terControl")
public class TerControlController {
    @Autowired
    private TerControlService terControlService;
    @Autowired
    private TokenService tokenService;
    @Autowired
    private MachineService machineService;
    @Autowired
    private RedisService redisService;
    @Autowired
    private AccountConfigService accountConfigService;
    @Autowired
    private MachineOccupyService machineOccupyService;
    @Autowired
    private DataService dataService;
    @Autowired
    private RuleRidePhotoLogDao ruleRidePhotoLogDao;
    @Autowired
    private TerControlApi terControlApi;

    /**
     * 发送指令
     */
    @RequestMapping("/sendControl")
    public JsonResult sendControl(String token, String userCode, String controlType, String paramName, String paramValue) {

        AccountUser accountUserToken = tokenService.getAccount(token);

        Assert.hasLength(userCode, "Machine.userCode.notNull");
        Assert.hasLength(controlType, "Machine.control.type.notNull");
        Assert.hasLength(paramName, "Machine.control.paramName.notNull");

        /**查询设备信息*/
        Machine machine = machineService.getByUseCode(userCode);
        if (machine == null) {
            throw new BaseException("Machine.notExist");
        }

        /**设备权限判断*/
        machineService.auth(accountUserToken.getAgents(), machine.getMachineId());

        if (controlType.equals(11)) {
            Integer value = dataService.getRoleConfig(accountUserToken.getAccountUserType() + RoleConfigConstant.MAIN_LOCK_VEHICLE);
            if (value != null && value.equals(1)) {
                /**获取配置，redis运维占用车辆*/
                AccountConfig accountConfig = accountConfigService.getByAccountId(accountUserToken.getAccountId());
                /**运维占用最大数判断*/
                if (accountConfig != null) {
                    if (accountConfig.getOccupyMax() != null && !accountConfig.getOccupyMax().equals(0)) {
                        Integer occupy = machineOccupyService.getByAccountUserId(accountUserToken.getAccountUserId());
                        if (occupy >= accountConfig.getOccupyMax()) {
                            throw new BaseException("Machine.occupyMax.exist");
                        }
                    }
                }
            }
        }

        /**生成流水号*/
        String serNO = UUID.randomUUID().toString();
        terControlService.sendControl(serNO, machine.getMachineNO(), controlType, paramName, paramValue);

        return JsonResult.succ(serNO);
    }

    /**
     * 业务控制
     */
    @RequestMapping("/control")
    public JsonResult<String> control(TerControlReqVO reqVO) {
        return JsonResult.succ(terControlService.control(reqVO));
    }

    /**
     * 获取结果
     */
    @RequestMapping("/getControlRet")
    public JsonResult getControlRet(String serNO) {
        Assert.hasLength(serNO, "Machine.control.serNO.notNull");

        String controlRet = redisService.get(RedisConstant.terControl + serNO);

        /**删除数据*/
        if (controlRet == null) {
            controlRet = "-1";
        } else {
            /**拍照*/
            if (controlRet.contains(ControlTypeConstant.HELMET) || controlRet.contains(ControlTypeConstant.MANNED_BOUND)) {
                String str1 = controlRet.substring(0, controlRet.indexOf("="));
                String str2 = controlRet.substring(str1.length() + 1);
                if ("OK".equals(str2)) {
                    controlRet = "1";
                } else {
                    controlRet = "-1";
                }
            }
        }
        return JsonResult.succ(controlRet);
    }

    /**
     * 获取拍照结果
     */
    @RequestMapping("/getControlRetPhoto")
    public JsonResult getControlRetPhoto(String serNO) {
        Assert.hasLength(serNO, "Machine.control.serNO.notNull");

        String controlRet = redisService.get(RedisConstant.PHOTO + serNO);
        RuleRidePhotoLog ruleRidePhotoLog = ruleRidePhotoLogDao.getFTPUrl(controlRet);
        if (ruleRidePhotoLog != null && ruleRidePhotoLog.getOssUrl() != null) {
            return JsonResult.succ(ruleRidePhotoLog.getOssUrl());
        } else {
            return JsonResult.succ("-1");
        }
    }

    /**
     * 批量调度开锁
     *
     * @param token      鉴权秘钥
     * @param userCode   车辆编号
     * @param type       指令类型
     * @param mapType    地图类型
     * @param lon        经度
     * @param lat        纬度
     * @param photograph 摄像头控制类型
     * @param helmetMac  头盔锁mac地址
     * @return
     */
    @RequestMapping("/controlBatch")
    public JsonResult controlBatch(String token, String userCode, Integer type,
                                   @RequestParam(defaultValue = "2") Integer mapType, Double lon, Double lat, Integer photograph, String helmetMac, Integer cameraType, Integer dispatch) {
        Assert.notNull(lon, "System.lon.notNull");
        Assert.notNull(lat, "System.lat.notNull");
        Assert.hasLength(userCode, "Machine.userCode.notNull");
        Assert.notNull(type, "Machine.control.type.notNull");
        Assert.notNull(dispatch, "Dispatch.state.notNull");
        AccountUser accountUser = tokenService.getAccount(token);
        List<String> notExistNO = terControlService.controlBatch(accountUser, Arrays.asList(userCode.split(",")), type
                , mapType, lon, lat, photograph, helmetMac, cameraType, dispatch)
                .stream().map(TerControlResult::getMachine).map(Machine::getUserCode).collect(Collectors.toList());
        return JsonResult.succ(notExistNO);
    }
    /**
     * @description: 获取车辆指令日志
     * @author: mo.shanyong
     * @date: 2025/2/26 16:42
     * @param: token
     * @param: terControlDTO
     * @return: com.tbit.main.common.JsonResult
     */
    @RequestMapping("/getOrderHis")
    public JsonResult getOrderHis(String token, TerControlDTO terControlDTO){
        AccountUser accountUser = tokenService.getAccount(token);
        //设置用户信息
        this.setUserInfo(accountUser,terControlDTO);
        Map<String, Object> dataMap = terControlApi.queryOrderHis(JSON.toJSONString(terControlDTO));
        return JsonResult.succ((Integer) dataMap.get("total"),dataMap.get("data"));
    }

    /**
     * @description: 获取还车指令日志
     * @author: mo.shanyong
     * @date: 2025/2/26 16:42
     * @param: token
     * @param: terControlDTO
     * @return: com.tbit.main.common.JsonResult
     */
    @RequestMapping("/queryReturnBikeLog")
    public JsonResult queryReturnBikeLog(String token, TerControlDTO terControlDTO){
        AccountUser accountUser = tokenService.getAccount(token);
        //设置用户信息
        this.setUserInfo(accountUser,terControlDTO);
        Map<String, Object> dataMap = terControlApi.queryReturnBikeLog(JSON.toJSONString(terControlDTO));
        return JsonResult.succ((Integer) dataMap.get("total"),dataMap.get("data"));
    }

    /**
     * @description: 设置用户信息
     * @author: mo.shanyong
     * @date: 2025/2/26 17:07
     * @param: accountUser
     * @param: terControlDTO
     */
    private void setUserInfo(AccountUser accountUser,TerControlDTO terControlDTO){
        terControlDTO.setAccountUserId(accountUser.getAccountUserId());
        terControlDTO.setBrandId(accountUser.getBrandId());
        terControlDTO.setAccountId(accountUser.getAccountId());
        terControlDTO.setAccountUserType(accountUser.getAccountUserType());
    }

}